﻿using System;
using GeoAPI.Geometries;

namespace YJKGridTopologyCal.Precision
{
	public class EnhancedPrecisionOp
	{
		private EnhancedPrecisionOp()
		{
		}

		public static IGeometry Intersection(IGeometry geom0, IGeometry geom1)
		{
			try
			{
				return geom0.Intersection(geom1);
			}
			catch (ApplicationException ex)
			{
			}
			IGeometry result;
			try
			{
				IGeometry geometry = new CommonBitsOp(true).Intersection(geom0, geom1);
				if (!geometry.IsValid)
				{
                    ApplicationException ex = new ApplicationException();
					throw ex;
				}
				result = geometry;
			}
			catch (ApplicationException)
			{
                ApplicationException ex = new ApplicationException();
				throw ex;
			}
			return result;
		}

		public static IGeometry Union(IGeometry geom0, IGeometry geom1)
		{
			try
			{
				return geom0.Union(geom1);
			}
			catch (ApplicationException ex)
			{
			}
			IGeometry result;
			try
			{
				IGeometry geometry = new CommonBitsOp(true).Union(geom0, geom1);
				if (!geometry.IsValid)
				{
                    ApplicationException ex = new ApplicationException();
					throw ex;
				}
				result = geometry;
			}
			catch (ApplicationException)
			{
                ApplicationException ex = new ApplicationException();
				throw ex;
			}
			return result;
		}

		public static IGeometry Difference(IGeometry geom0, IGeometry geom1)
		{
			try
			{
				return geom0.Difference(geom1);
			}
			catch (ApplicationException ex)
			{
			}
			IGeometry result;
			try
			{
				IGeometry geometry = new CommonBitsOp(true).Difference(geom0, geom1);
				if (!geometry.IsValid)
				{
					ApplicationException ex = new ApplicationException();
					throw ex;
				}
				result = geometry;
			}
			catch (ApplicationException)
			{
                ApplicationException ex = new ApplicationException();
				throw ex;
			}
			return result;
		}

		public static IGeometry SymDifference(IGeometry geom0, IGeometry geom1)
		{
			try
			{
				return geom0.SymmetricDifference(geom1);
			}
			catch (ApplicationException ex)
			{
			}
			IGeometry result;
			try
			{
				IGeometry geometry = new CommonBitsOp(true).SymDifference(geom0, geom1);
				if (!geometry.IsValid)
				{
                    ApplicationException ex = new ApplicationException();
					throw ex;
				}
				result = geometry;
			}
			catch (ApplicationException)
			{
                ApplicationException ex = new ApplicationException();
				throw ex;
			}
			return result;
		}

		[Obsolete("This method should no longer be necessary, since the buffer algorithm now is highly robust.")]
		public static IGeometry Buffer(IGeometry geom, double distance)
		{
			try
			{
				return geom.Buffer(distance);
			}
			catch (ApplicationException ex)
			{
			}
			IGeometry result;
			try
			{
				IGeometry geometry = new CommonBitsOp(true).Buffer(geom, distance);
				if (!geometry.IsValid)
				{
                    ApplicationException ex = new ApplicationException();
					throw ex;
				}
				result = geometry;
			}
			catch (ApplicationException)
			{
                ApplicationException ex = new ApplicationException();
				throw ex;
			}
			return result;
		}
	}
}
